/*
 * $Id$
 */
package corejs.parser;

import corejs.stmt.Block;
import corejs.stmt.FunctionDeclaration;
import corejs.stmt.Statement;
import corejs.Token;
import corejs.expr.FunctionExpr;
import java.util.ArrayList;
import java.util.List;

import static corejs.JsTokenType.*;

/**
 *
 * @author myang
 */
public class FunctionParser implements StatementParser, PrefixParser {

   @Override
   public FunctionExpr expr(final PrattParser parser, final Token tk) {
      final String name = parseName(parser);
      final String[] args = parseArguments(parser);
      final Block body = parseBody(parser);
      return new FunctionExpr(name, args, body);
   }

   @Override
   public Statement statement(final PrattParser parser) { 
      return new FunctionDeclaration(expr(parser, null));//parser.nextToken()));
   }

   private String parseName(final PrattParser parser) {
      final Token tk = parser.nextToken();
      if (tk.is(NAME)) {
         parser.nextToken(LEFT_PAREN);
         return tk.text();
      }
      else if (tk.is(LEFT_PAREN)) {
         return "";
      }
      else {
         throw new ParseException("( is expected!");
      }
   }

   private String[] parseArguments(final PrattParser parser) {
      final List<String> args = new ArrayList<String>();
      if (!parser.match(RIGHT_PAREN)) {
         do {
            args.add(parser.nextToken(NAME).text());
         } while (parser.match(COMMA));
         parser.nextToken(RIGHT_PAREN);
      }
      return args.toArray(new String[0]);
   }

   private Block parseBody(final PrattParser parser) {
      parser.nextToken(LEFT_BRACE);
      return parser.block(RIGHT_BRACE);
   }
}
